package top.wenzz.manage.system.manage.service;

import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.wenzz.manage.system.manage.dao.SysPermissionDao;
import top.wenzz.manage.system.manage.entity.SysPermission;
import top.wenzz.manage.system.manage.entity.SysResources;
import top.wenzz.commons.service.BasicService;
import top.wenzz.commons.utils.StringUtils;
import top.wenzz.commons.vo.PageRequest;

import java.util.*;

/**
 * Created by 钟廷员 on 2016/12/12.
 */
@Service
public class SysPermissionService extends BasicService<SysPermission, SysPermissionDao> {

    @Override
    public Map<String, Object> find(SysPermission entity, PageRequest pageRequest) {
        List<SysPermission> list = createTree(super.dao.findAll());
        return toExtjsQuery(list, 0, pageRequest);
    }

    @Transactional
    public String updateResources(SysPermission entity) throws Exception {
        SysPermission e = getOne(entity.getId());
        if(e == null)
            return "不存在该数据";
        if(e.getVersion() != entity.getVersion())
            return "数据已被修改，请刷新后操作";
        e.setResources(entity.getResources());
        updateEntity(e);
        return null;
    }

    @Transactional
    public void initSpringSecurityPermission(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry urlRegistry) throws Exception {
        Map<String, Set<String>> map = new HashMap<>();
        for(SysPermission permission : this.findAll()) {
            if(StringUtils.isEmpty(permission.getSn()))
                continue;
            for(SysResources resources : permission.getResources()) {
                if(!map.containsKey(resources.getUrl()))
                    map.put(resources.getUrl(), new HashSet<>());
                map.get(resources.getUrl()).add(permission.getSn());
            }

            for(Map.Entry<String, Set<String>> entry : map.entrySet()) {
                urlRegistry = ((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)urlRegistry.antMatchers(entry.getKey())).hasAnyRole(entry.getValue().toArray(new String[entry.getValue().size()]));
            }
        }
    }

    public static List<SysPermission> createTree(List<SysPermission> permissions) {
        Set<Integer> authoritys_set = new TreeSet<>();
        // 以父节点生成MAP
        Map<Integer, List<SysPermission>> map = new HashMap<>();
        List<SysPermission> list = new ArrayList<>();
        permissions.forEach(authority -> {
            if(authoritys_set.contains(authority.getId()))
                return;
            authoritys_set.add(authority.getId());

            if (!map.containsKey(authority.getPid())) {
                map.put(authority.getPid(), new ArrayList<>());
            }
            map.get(authority.getPid()).add(authority);
            if(authority.getPid() == 0)
                list.add(authority);
        });
        createTree(list, map);
        return list;
    }

    private static void createTree(List<SysPermission> authoritys, Map<Integer, List<SysPermission>> map) {
        // 排序
        authoritys.sort(Comparator.comparingInt(SysPermission::getWeight));
        authoritys.forEach(p -> {
            if (map.containsKey(p.getId())) {
                p.setChildren(map.get(p.getId()));
                createTree(map.get(p.getId()), map);
            } else {
                p.getChildren().clear();
            }
        });
    }
}
